home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / elm / elm2.4 / lib / aliasdb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-20  |  5.7 KB  |  229 lines

  1. /*******************************************************************************
  2.  *  The Elm Mail System  -  $Revision: 5.3 $   $State: Exp $
  3.  *
  4.  *            Copyright (c) 1988-1992 USENET Community Trust
  5.  *            Copyright (c) 1986,1987 Dave Taylor
  6.  *******************************************************************************
  7.  * Bug reports, patches, comments, suggestions should be sent to:
  8.  *
  9.  *    Syd Weinstein, Elm Coordinator
  10.  *    elm@DSI.COM            dsinc!elm
  11.  *
  12.  *******************************************************************************
  13.  * $Log: aliasdb.c,v $
  14.  * Revision 5.3  1993/04/21  01:40:12  syd
  15.  * add seekset define
  16.  *
  17.  * Revision 5.2  1993/04/12  01:53:38  syd
  18.  * Added fetch_alias() and next_addr_in_list() routines for use in
  19.  * new elmalias utility.
  20.  * From: chip@chinacat.unicom.com (Chip Rosenthal)
  21.  *
  22.  * Revision 5.1  1992/12/20  05:14:05  syd
  23.  * Initial checkin
  24.  *
  25.  *
  26.  ******************************************************************************/
  27.  
  28. /** Alias interface with dbz routines.
  29.  
  30.     This code is shared with newalias and elm so that
  31.   it is easier to do updates while in elm.  The routines in
  32.   this file are interface routines between elm alias code,
  33.   newalias, and listalias and the dbm routines.
  34.  
  35. **/
  36.  
  37. #include "headers.h"
  38. #include <ctype.h>
  39. #include "ndbz.h"
  40.  
  41. #ifndef SEEK_SET
  42. #define    SEEK_SET    0    /* Set file pointer to "offset" */
  43. #define    SEEK_CUR    1    /* Set file pointer to current plus "offset" */
  44. #define    SEEK_END    2    /* Set file pointer to EOF plus "offset" */
  45. #endif
  46.  
  47. #ifdef BSD
  48. #  include <sys/file.h>
  49. #  undef tolower
  50. #  undef toupper
  51. #endif
  52.  
  53. /* byte-ordering stuff */
  54. #define    MAPIN(o)    ((db->dbz_bytesame) ? (of_t) (o) : bytemap((of_t)(o), db->dbz_conf.bytemap, db->dbz_mybmap))
  55. #define    MAPOUT(o)    ((db->dbz_bytesame) ? (of_t) (o) : bytemap((of_t)(o), db->dbz_mybmap, db->dbz_conf.bytemap))
  56.  
  57. static of_t            /* transformed result */
  58. bytemap(ino, map1, map2)
  59. of_t ino;
  60. int *map1;
  61. int *map2;
  62. {
  63.     union oc {
  64.         of_t o;
  65.         char c[SOF];
  66.     };
  67.     union oc in;
  68.     union oc out;
  69.     register int i;
  70.  
  71.     in.o = ino;
  72.     for (i = 0; i < SOF; i++)
  73.         out.c[map2[i]] = in.c[map1[i]];
  74.     return(out.o);
  75. }
  76.  
  77. read_one_alias(db, ar)
  78. DBZ *db;
  79. struct alias_rec *ar;
  80. {
  81. /*
  82.  *    Read an alias (name, address, etc.) from the data file
  83.  */
  84.  
  85.     FILE *data_file = db->dbz_basef;
  86.  
  87.     if (data_file == NULL)
  88.         return(0);    /* no alias file, but hash exists, error condition */
  89.  
  90.     if (fread((char *) ar, sizeof(struct alias_rec), 1, data_file) <= 0)
  91.         return(0);
  92.  
  93.     ar->status = (int) MAPIN(ar->status);
  94.     ar->alias = (char *) MAPIN(ar->alias);
  95.     ar->last_name = (char *) MAPIN(ar->last_name);
  96.     ar->name = (char *) MAPIN(ar->name);
  97.     ar->comment = (char *) MAPIN(ar->comment);
  98.     ar->address = (char *) MAPIN(ar->address);
  99.     ar->type = (int) MAPIN(ar->type);
  100.     ar->length = (long) MAPIN(ar->length);
  101.  
  102.     return(1);
  103. }
  104.  
  105.  
  106. /*
  107.  * Retrieve an alias record and information from a database.
  108.  *
  109.  * If "alias" is non-NULL, it is the name of the alias to fetch (searching
  110.  * is case insensitive).  If the alias is found, we return a pointer to
  111.  * dynamically allocated memory that holds an alias record *plus* the
  112.  * text data for that record.  If the lookup fails or an error occurs,
  113.  * then a NULL is returned.
  114.  *
  115.  * If "alias" is NULL then the next alias in the database is retrieved.
  116.  * This may be used to scan through the database.  Again, a pointer to
  117.  * dynamically allocated memory is returned.  When the end of file is
  118.  * reached, a NULL is returned.
  119.  */
  120. struct alias_rec *fetch_alias(db, alias)
  121. DBZ *db;
  122. char *alias;
  123. {
  124.     datum key, val;
  125.     struct alias_rec arec;
  126.     long pos;
  127.     register struct alias_rec *ar;
  128.     register char *buf, *s;
  129.  
  130.     /*
  131.      * If an alias is specifed then locate it.
  132.      */
  133.     if (alias != NULL) {
  134.  
  135.         /*
  136.          * Fetch location of this alias.
  137.          */
  138.         key.dptr = safe_strdup(alias);
  139.         for (s = key.dptr ; *s != '\0' ; ++s) {
  140.             if (isascii(*s) && isupper(*s))
  141.                 *s = tolower(*s);
  142.         }
  143.         key.dsize = strlen(alias);
  144.         val = dbz_fetch(db, key);
  145.         (void) free((malloc_t)key.dptr);
  146.  
  147.         /*
  148.          * Make sure the alias was found.
  149.          */
  150.         if (val.dptr == NULL)
  151.             return (struct alias_rec *)NULL;
  152.  
  153.         /*
  154.          * Sanity check - return value should be a seek offset.
  155.          */
  156.         if (val.dsize != sizeof(long))
  157.             return (struct alias_rec *)NULL;
  158.  
  159.         /*
  160.          * Move to the position of the selected alias record.
  161.          */
  162.         pos = *((long *)(val.dptr)) - sizeof(struct alias_rec);
  163.         if (fseek(db->dbz_basef, pos, SEEK_SET) != 0)
  164.             return (struct alias_rec *)NULL;
  165.  
  166.     }
  167.  
  168.     /*
  169.      * We are now positioned at the alias record we want.  Pull it in.
  170.      */
  171.     if (!read_one_alias(db, &arec))
  172.         return (struct alias_rec *)NULL;
  173.  
  174.     /*
  175.      * Allocate space to hold the alias record and data content.
  176.      */
  177.     ar = (struct alias_rec *)
  178.         safe_malloc(sizeof(struct alias_rec) + arec.length);
  179.     *ar = arec;
  180.     buf = (char *)ar + sizeof(struct alias_rec);
  181.  
  182.     /*
  183.      * Read in the data content and fixup pointers in the alias record.
  184.      */
  185.     if (fread(buf, ar->length, 1, db->dbz_basef) != 1)
  186.         return (struct alias_rec *)NULL;
  187.     ar->alias += (int) buf;
  188.     ar->last_name += (int) buf;
  189.     ar->name += (int) buf;
  190.     ar->comment += (int) buf;
  191.     ar->address += (int) buf;
  192.  
  193.     return ar;
  194. }
  195.  
  196.  
  197. /*
  198.  * Return a pointer to the next address in this list, and update the pointer
  199.  * to the list.  Addresses are seperated by whitespace and/or commas.
  200.  * Return NULL when list finished.  This routine scribbles on the list.
  201.  */
  202. char *next_addr_in_list(aptr)
  203. char **aptr;
  204. {
  205.     register char *front, *back;
  206.  
  207.     /*
  208.      * Locate the first letter of the address.
  209.      */
  210.     front = *aptr;
  211.     while (*front == ',' || isspace(*front))
  212.         ++front;
  213.     if (*front == '\0')
  214.         return (char *) NULL;
  215.  
  216.     /*
  217.      * Locate the end of the address.
  218.      */
  219.     back = front;
  220.     while (*back != '\0' && *back != ',' & !isspace(*back))
  221.         ++back;
  222.     if (*back != '\0')
  223.         *back++ = '\0';
  224.  
  225.     *aptr = back;
  226.     return front;
  227. }
  228.  
  229.